from Common.EventHandle import EventHandle
from Calendar.Calendar import *
from FinancialAsset.AssetFactory import *
from DataFeeder.QueryQuote import *
from Misc.QuoteType import *

from DataAccess.DBConnFactory import *
from string import Template

class xRSI(EventHandle):

	def __init__(self, start_date, end_date, stock_size, length, freq = Frequency.Monthly):
	
		sd = offset_date_by_month(start_date, -1)
		update_dates = TradingCalendar(['CNSESH']).date_series(sd, end_date, Frequency.Daily)
		
		self.trd_dates = TradingCalendar(['CNSESH']).date_series(start_date, end_date, freq, DayRollingConv.Preceding)
		
		EventHandle.__init__(self, update_dates)
		
		self.stock_size = stock_size
		self.length = length
		self.rsi_xavg = {}

	def create_activities(self, ref_date, portf = None):
		
		r = day_rsi(ref_date)
		
		for elem in r:
		
			if self.rsi_xavg.has_key(elem[0]):
				self.rsi_xavg[elem[0]] = (self.length - 1)/float(self.length)*self.rsi_xavg[elem[0]] + 1/float(self.length)*elem[1]
			else:
				self.rsi_xavg[elem[0]] = elem[1]
				
		print 'running info, updating xaverage of rsi completed...', ref_date
		
		# Trade
		if ref_date in self.trd_dates:
			
			print '   start trade...', ref_date
			
			holding = portf.holding(ref_date)
			print '   step 1, acquring holding completed...', len(holding)
		
			nav = portf.nav(ref_date)
			print '   step 2, acquring nav completed...', nav
		
			rsi_xavg = self.rsi_xavg
			rsi_xavg = sorted(rsi_xavg.iteritems(), key=lambda rsi_xavg:rsi_xavg[1], reverse=True)
		
			l_pool = set()
			for i in range(self.stock_size):
				l_pool.add(AssetFactory().acquire_asset('STOCK', rsi_xavg[i][0]))
				
			#s_pool = set()
			#for i in range(len(rsi_xavg) - self.stock_size, len(rsi_xavg)):
			#	s_pool.add(AssetFactory().acquire_asset('STOCK', rsi_xavg[i][0]))
		
			print '   step 3, acquring stock pool completed...', len(l_pool)
			
			activities = []
			
			for sec, quantity in holding.iteritems():
				if sec.type_name() == 'STOCK':
					
					close = QuoteRegister().get_stock_quote(ref_date, sec.ticker(), QuoteType.CLOSE)
					cash = AssetFactory().acquire_asset('CASH', sec.currency())
					
					activities.append((ref_date, sec, -quantity))
					activities.append((ref_date, cash, quantity*close))

			for sec in l_pool:
				
				close = QuoteRegister().get_stock_quote(ref_date, sec.ticker(), QuoteType.CLOSE)
				
				if close and close > 0:
					cash = AssetFactory().acquire_asset('CASH', sec.currency())
					quantity = int(nav/len(l_pool)/close)
					
					activities.append((ref_date, sec, quantity))
					activities.append((ref_date, cash, -quantity*close))
					
			print '   step 4, create activies completed...', len(activities)
			
			return activities
		
	@staticmethod	
	def event_name():
		return 'xRSI'


def day_rsi(ref_date):

	sql_tpl = Template('''select SYMBOL, (TCLOSE - LOW) / (HIGH - LOW) as rsi
							 from CHDQUOTE
							where TDATE = '${DATE}'
							  and VOTURNOVER > 0
							  and (HIGH / LOW - 1) >= 0.02''')
												   
	sql_text = sql_tpl.substitute(DATE = ref_date.strftime('%Y%m%d'))
	
	cursor = DBConnFactory().get_db_connection('FINCHINA').cursor()								  
	cursor.execute(sql_text)
	return cursor.fetchall()
	
	
	